package ru.myrtle.umf.codegen.java;

import java.io.IOException;
import java.io.Reader;
import java.util.HashSet;
import java.util.Set;

import ru.myrtle.umf.codegen.Resource;

public class JavaFile {

    private static final String NL = System.getProperties().getProperty("line.separator");
    private static final String EMPTY = "";

    private Set<String> imports = new HashSet<String>();

    public Set<String> getImports() {
        return imports;
    }

    private String implementsSection = EMPTY;

    public String getImplementsSection() {
        return implementsSection;
    }
    
    private String code = NL;
    
    public String getCode() {
        return code;
    }

    /*
     *
     */

    private static String loadToString(Reader reader) throws IOException {
        StringBuffer b = new StringBuffer();

        char[] buffer = new char[1024];
        int charsRead;

        while ((charsRead = reader.read(buffer)) > 0) {
            b.append(buffer, 0, charsRead);
        }

        return b.toString();
    }

    private void decomposeImpl(Resource resource) throws Exception {
        if (resource.exists()) {
            Reader reader = resource.getReader();

            try {
                String body = loadToString(reader);

                int classIndex = body.indexOf("class ");
                int classCodeBracketIndex = body.indexOf("{", classIndex);
                int classCodeStartIndex = classCodeBracketIndex + 1;
                int classCodeEndIndex = body.lastIndexOf("}");

                code += "    " + body.substring(classCodeStartIndex, classCodeEndIndex).trim();

                int implementsStartIndex = body.indexOf("implements ", classIndex);
                if (implementsStartIndex > 0 && implementsStartIndex < classCodeStartIndex) {
                    implementsSection = body.substring(
                            implementsStartIndex, classCodeBracketIndex
                    ).trim();
                }

                int annotationMarkerIndex = body.indexOf("@");
                if (annotationMarkerIndex < 0) {
                    annotationMarkerIndex = Integer.MAX_VALUE;
                }

                int commentMarkerIndex = body.indexOf("/*");
                if (commentMarkerIndex < 0) {
                    commentMarkerIndex = Integer.MAX_VALUE;
                }

                int endPositionForImports = Integer.MAX_VALUE;

                if (endPositionForImports > annotationMarkerIndex) {
                    endPositionForImports = annotationMarkerIndex;
                }
                if (endPositionForImports > commentMarkerIndex) {
                    endPositionForImports = commentMarkerIndex;
                }
                if (endPositionForImports > classIndex) {
                    endPositionForImports = classIndex;
                }

                extractImports(
                        body.substring(
                                0,
                                Math.min(
                                        annotationMarkerIndex, endPositionForImports
                                )
                        )
                );
            }
            finally {
                reader.close();
            }
        }
    }

    private int extractSingleImport(String text, int startIndex) {
        int importStartIndex = text.indexOf("import", startIndex);
        if (importStartIndex < 0) {
            return -1; // а кончились все импорты.
        }

        int importEndIndex = text.indexOf(";", importStartIndex);
        if (importEndIndex < 0) {
            return -1; // хрень какую-то нам подсунули, такой импорт пусть сами разбирают.
        }

        String importLine = text.substring(
                importStartIndex + "import".length(), importEndIndex
        );
        importLine = importLine.trim();
        
        imports.add(importLine);

        return importEndIndex;
    }

    private void extractImports(String text) {
        int index = 0;

        while (index >= 0) {
            index = extractSingleImport(
                    text, index
            );
        }
    }

    public void decompose(Resource resource) {
        try {
            decomposeImpl(resource);
        }
        catch (Exception thrown) {

            System.out.println("decompose error: " + resource);

            throw new RuntimeException(
                    thrown.getMessage(), thrown
            );
        }
    }

    public static void main(String... args) {
        Resource resource = new Resource(
                new java.io.File("D:/_"), "cp1251"
        );

        resource.setObjectPackage("");
        resource.setObjectFileName("Imports");
        resource.setObjectFileExtension("java");

        JavaFile javaFile = new JavaFile();
        javaFile.decompose(resource);

        System.out.println(
                "imports = " + javaFile.getImports()
        );
        System.out.println(
                "implements = " + javaFile.getImplementsSection()
        );
        System.out.println(
                "code = " + javaFile.getCode()
        );
    }
}
